namespace muduoDotNet
{
    /// <summary>
    /// EventLoopThreadPool类，用于管理多个EventLoopThread对象
    /// </summary>
    public class EventLoopThreadPool : IDisposable
    {
        private readonly EventLoop _baseLoop;
        private readonly string _nameArg;
        private bool _started;
        private int _numThreads;
        private int _next;
        private readonly List<EventLoopThread> _threads;
        private readonly List<EventLoop> _loops;
        private bool _disposed;

        public EventLoopThreadPool(EventLoop baseLoop, string name = "")
        {
            _baseLoop = baseLoop ?? throw new ArgumentNullException(nameof(baseLoop));
            _nameArg = name;
            _started = false;
            _numThreads = 0;
            _next = 0;
            _threads = new List<EventLoopThread>();
            _loops = new List<EventLoop>();
            _disposed = false;
        }

        public EventLoop BaseLoop => _baseLoop;
        public string Name => _nameArg;

        /// <summary>
        /// 设置线程池大小
        /// </summary>
        public int ThreadsNum
        {
            get { return _numThreads; }
            set { _numThreads = value; }
        }

        /// <summary>
        /// 启动线程池
        /// </summary>
        public void Start()
        {
            if (!_started)
            {
                _baseLoop.AssertInLoopThread();
                _started = true;

                for (int i = 0; i < _numThreads; ++i)
                {
                    string threadName = string.IsNullOrEmpty(_nameArg) ? "EventLoopThread" : $"{_nameArg}-{i}";
                    var t = new EventLoopThread();
                    _threads.Add(t);
                    var loop = t.StartLoop();
                    _loops.Add(loop);
                }
            }
        }

        /// <summary>
        /// 使用轮询方式获取下一个EventLoop
        /// </summary>
        /// <returns>EventLoop对象</returns>
        public EventLoop GetNextLoop()
        {
            _baseLoop.AssertInLoopThread();
            if (!_started)
            {
                throw new NetException("Not started");
            }

            // 如果没有工作线程，使用基础EventLoop
            EventLoop loop = _baseLoop;
            
            if (_loops.Count > 0)
            {
                // 轮询获取下一个EventLoop
                loop = _loops[_next];
                _next = (_next + 1) % _loops.Count;
            }
            
            return loop;
        }

        /// <summary>
        /// 获取所有EventLoop
        /// </summary>
        /// <returns>EventLoop列表</returns>
        public List<EventLoop> GetAllLoops()
        {
            _baseLoop.AssertInLoopThread();
            if (!_started)
            {
                throw new NetException("Not started");
            }
            
            if (_loops.Count == 0)
            {
                return new List<EventLoop> { _baseLoop };
            }
            
            return new List<EventLoop>(_loops);
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                
                foreach (var t in _threads)
                {
                    t.Dispose();
                }
                
                _threads.Clear();
                _loops.Clear();
            }
        }
    }
}